/**
 * PropertiesExporter.java
 * Created on 10 15, 07
 */
package com.pacm.i18n;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;


/**
 * Exports property files from an MS Excel sheet
 *
 * @author Paul Augustine C. Mendoza
 * @since 1.0
 */
public class PropertiesExporter {

    private static final String OUTPUT = "ApplicationResources";

    private static final String EXTENSION = ".properties";

    private static final Locale DEFAULT_LOCALE = Locale.ENGLISH;

    /**
     * Main launcher
     *
     * @param args
     */
    public static void main(String[] args) {
        new PropertiesExporter().export(args[0]);
    }

    /**
     * Exports resource bundles from a single Excel sheet
     */
    @SuppressWarnings("unchecked")
    private void export(String inputFile) {
        try {
            InputStream input = this.getClass().getClassLoader()
                    .getResourceAsStream(inputFile);
            POIFSFileSystem fs = new POIFSFileSystem(input);
            HSSFWorkbook wb = new HSSFWorkbook(fs);
            HSSFSheet sheet = wb.getSheetAt(0);
            HSSFRow headers = sheet.getRow((short) 0);
            String[] locales = null;
            int validColCount = 0;
            int colCount = headers.getPhysicalNumberOfCells();
            if (colCount < 1) {
                System.out.println("Malformed input file!");
                return;
            } else {
                // Truncate valid columns
                for (int i = 0; i < colCount; i++) {
                    HSSFCell cell = headers.getCell((short) (i + 1));
                    if (cell == null) {
                        break;
                    } else {
                        validColCount++;
                    }
                }
                locales = new String[validColCount];
                for (int idx = 0; idx < locales.length; idx++) {
                    HSSFCell cell = headers.getCell((short) (idx + 1));
                    if (cell == null) {
                        break;
                    }
                    locales[idx] = cell.getRichStringCellValue().getString();
                }
            }
            int idx = 1;
            Map<String, Collection> bundleMap = new HashMap<String, Collection>();
            for (String locale : locales) {
                System.out.println("Locale = " + locale);
                Collection<KeyValue> bundleCollection = new ArrayList<KeyValue>();
                Iterator iterator = sheet.rowIterator();
                while (iterator.hasNext()) {
                    HSSFRow row = (HSSFRow) iterator.next();
                    if (row.getCell((short) 0) == null) {
                        // Skip spaces
                        continue;
                    }
                    String key = row.getCell((short) 0)
                            .getRichStringCellValue().getString();
                    if (key.startsWith("#") || StringUtils.isWhitespace(key)) {
                        // Skip comments
                        continue;
                    }
                    HSSFCell valueCell = row.getCell((short) idx);
                    String valueStr = "";
                    if (valueCell != null) {
                        switch (valueCell.getCellType()) {
                        case HSSFCell.CELL_TYPE_STRING:
                            valueStr = (valueCell == null) ? "" : valueCell
                                    .getRichStringCellValue().toString();
                            break;
                        case HSSFCell.CELL_TYPE_BOOLEAN:
                            valueStr = String.valueOf(valueCell
                                    .getBooleanCellValue());
                            break;
                        case HSSFCell.CELL_TYPE_NUMERIC:
                            valueStr = String.valueOf(valueCell
                                    .getNumericCellValue());
                            break;
                        }
                    }
                    KeyValue keyValue = new KeyValue();
                    keyValue.setKey(key);
                    keyValue.setValue(valueStr);
                    bundleCollection.add(keyValue);
                }
                idx++;
                bundleMap.put(locale, bundleCollection);
            }
            generateResourceBundles(bundleMap);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * Generates the resource bundles
     *
     * @param resourceBundles
     */
    @SuppressWarnings("unchecked")
    private void generateResourceBundles(Map<String, Collection> bundleMap) {
        Set<String> keySet = bundleMap.keySet();
        File bundle = null;
        for (String locale : keySet) {
            // Create file
            BufferedWriter out = null;
            try {
                bundle = new File(OUTPUT + "_" + locale + EXTENSION);
                out = new BufferedWriter(new FileWriter(bundle));
                Collection<KeyValue> keyValues = bundleMap.get(locale);
                for (KeyValue keyValue : keyValues) {
                    out.write(keyValue.getKey() + "=" + keyValue.getValue());
                    out.newLine();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (out != null) {
                    try {
                        out.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            // Copy default
            if (locale.equalsIgnoreCase(DEFAULT_LOCALE.getLanguage())) {
                File defaultBundle = new File(OUTPUT + EXTENSION);
                try {
                    FileUtils.copyFile(bundle, defaultBundle);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
